﻿
Imports System.Threading
Imports threadpoolCommon
Imports tp = System.Threading.ThreadPool

Public Class managedThreadPool
    Implements ithreadpool

    Private work As ParameterizedThreadStart = Nothing
    Private stopsignal As Boolean = False
    Private _timelimitOperationEnabled As Boolean = True

    Public Sub New(ByVal work As ParameterizedThreadStart, Optional ByVal threadCount As Int64 = 0)
        AddHandler applicationShutdown, AddressOf [stop]
        Me.work = work
        start(threadCount)
    End Sub

    Public Sub New(ByVal threadCount As Int64)
        Me.New(Nothing, threadCount)
    End Sub

    Public Sub New()
        Me.New(defaultThreadCount())
    End Sub

    Public Sub disableTimeLimitOperation() Implements ithreadpool.disableTimeLimitOperation
        _timelimitOperationEnabled = False
    End Sub

    Public Sub enableTimeLimitOperation() Implements ithreadpool.enableTimeLimitOperation
        _timelimitOperationEnabled = True
    End Sub

    Public Function timelimitOperationEnabled() As Boolean
        Return _timelimitOperationEnabled AndAlso timelimitOperation.enabled()
    End Function

    Private Sub workthread(ByVal work As workInfo)
        workOn(work, timelimitOperationEnabled:=timelimitOperationEnabled())
    End Sub

    Private Sub workthread(ByVal obj As Object)
        workthread(convertor.cast(Of workInfo)(obj))
    End Sub

    Public Sub insertJob(ByVal obj As Object) Implements ithreadpool.insertJob
        insertJob(work, obj)
    End Sub

    Public Sub insertJob(ByVal work As ParameterizedThreadStart, ByVal obj As Object) Implements ithreadpool.insertJob
        tp.QueueUserWorkItem(AddressOf workthread, New workInfo(work, obj))
    End Sub

    Protected Sub start(ByVal threadCount As Int64)
        Me.threadCount() = threadCount
        stopsignal = False
    End Sub

    Public Sub [stop](Optional ByVal stopWaitSeconds As Int64 = defaultStopWaitSeconds) Implements ithreadpool.stop
        stopsignal = True
    End Sub

    Public Function stopping() As Boolean Implements ithreadpool.stopping
        Return stopsignal
    End Function

    Public Property threadCount As Int64 Implements ithreadpool.threadCount
        Get
            Dim ft As Int32 = 0
            Dim bt As Int32 = 0
            tp.GetMaxThreads(ft, bt)
            Return ft + bt
        End Get
        Set(ByVal value As Int64)
            tp.SetMaxThreads(value >> 1, value >> 1)
        End Set
    End Property

    Public Shared ReadOnly [global] As managedThreadPool = Nothing

    Shared Sub New()
        [global] = New managedThreadPool()
    End Sub

    Public Shared Sub register(ByVal resolver As resolver)
        resolver.register(Of ithreadpool)([global])
        resolver.register([global])
    End Sub

    Public Shared Sub register()
        register(resolver.global)
    End Sub
End Class
